package com.cndw.kungfu.model.disciple.domain;

import java.util.HashMap;
import java.util.Map;

import com.cndw.asyncsync.SyncObject;
import com.cndw.kungfu.config.DiscipleConfig;
import com.cndw.kungfu.domain.LevelUpgrade;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.ext.JsonProcesser;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.disciple.DiscipleDower;
import com.cndw.kungfu.model.player.FormulaScore;
import com.cndw.kungfu.vo.DiscipleSmallVO;
import com.cndw.kungfu.vo.DiscipleVO;

/**
 * 门派徒弟实体类
 * 
 * @author fantadust [9677889@qq.com]
 * @date 2011-6-23 下午05:16:47
 */
public class Disciple extends SyncObject {
	/**
	 * 唯一编号
	 */
	private int id;
	/**
	 * 玩家id
	 */
	private long playerId;
	/**
	 * 徒弟id
	 */
	private int discipleId;
	/**
	 * 名称
	 */
	private String name;
	private int icon;

	/**
	 * 徒弟等级
	 */
	private int level;
	/**
	 * 经验
	 */
	private long exp;

	private int power;
	private int physical;
	private int agile;
	private int wit;
	private int powerPercent;
	private int physicalPercent;
	private int agilePercent;
	private int witPercent;

	private int powerAdd;
	private int physicalAdd;
	private int agileAdd;
	private int witAdd;
	/**
	 * 友好度
	 */

	/**
	 * 评分
	 */
	private int score;
	/**
	 * 天赋
	 */
	private String dower;
	/**
	 * 创建时间
	 */
	private int createTime;
	/**
	 * 助阵营id
	 */
	private int campId;
	/**
	 * 工种id
	 */
	private int workId;
	/**
	 * 职务id
	 */
	private int position;
	/**
	 * 系统上次处理时间
	 */
	public int lastSysHandle;
	public int intimate;
	/**
	 * 品质
	 */
	private int quality;
	/**
	 * 成长值
	 */
	private int growth;
	/**
	 * 特性类型
	 */
	private int featureType;
	/**
	 * 特性等级
	 */
	private int featureLevel;
	/**
	 * 特训次数
	 */
	private int devilTimes;
	/**
	 * 武功标记
	 */
	private int gestSign;

	private Map<Integer, Integer> dowerMap = new HashMap<Integer, Integer>();
	
	private transient int[] featrueTmp;

	public Disciple() {

	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getIcon() {
		return icon;
	}

	public void setIcon(int icon) {
		this.icon = icon;
	}

	public long getPlayerId() {
		return playerId;
	}

	public void setPlayerId(long playerId) {
		this.playerId = playerId;
	}

	public int getDiscipleId() {
		return discipleId;
	}

	public void setDiscipleId(int discipleId) {
		this.discipleId = discipleId;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public long getExp() {
		return exp;
	}

	public void setExp(long exp) {
		this.exp = exp;
	}

	public int getPower() {
		return power;
	}

	public void setPower(int power) {
		this.power = power;
	}

	public int getPhysical() {
		return physical;
	}

	public void setPhysical(int physical) {
		this.physical = physical;
	}

	public int getAgile() {
		return agile;
	}

	public void setAgile(int agile) {
		this.agile = agile;
	}

	public int getWit() {
		return wit;
	}

	public void setWit(int wit) {
		this.wit = wit;
	}

	public int getPowerPercent() {
		return powerPercent;
	}

	public void setPowerPercent(int powerPercent) {
		this.powerPercent = powerPercent;
	}

	public int getPhysicalPercent() {
		return physicalPercent;
	}

	public void setPhysicalPercent(int physicalPercent) {
		this.physicalPercent = physicalPercent;
	}

	public int getAgilePercent() {
		return agilePercent;
	}

	public void setAgilePercent(int agilePercent) {
		this.agilePercent = agilePercent;
	}

	public int getWitPercent() {
		return witPercent;
	}

	public void setWitPercent(int witPercent) {
		this.witPercent = witPercent;
	}

	public int getPowerAdd() {
		return powerAdd;
	}

	public void setPowerAdd(int powerAdd) {
		this.powerAdd = powerAdd;
	}

	public int getPhysicalAdd() {
		return physicalAdd;
	}

	public void setPhysicalAdd(int physicalAdd) {
		this.physicalAdd = physicalAdd;
	}

	public int getAgileAdd() {
		return agileAdd;
	}

	public void setAgileAdd(int agileAdd) {
		this.agileAdd = agileAdd;
	}

	public int getWitAdd() {
		return witAdd;
	}

	public void setWitAdd(int witAdd) {
		this.witAdd = witAdd;
	}

	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}

	public int getQuality() {
		return quality;
	}

	public void setQuality(int quality) {
		this.quality = quality;
	}

	public int getGrowth() {
		return growth;
	}

	public void setGrowth(int growth) {
		this.growth = growth;
	}

	public int getFeatureType() {
		return featureType;
	}

	public void setFeatureType(int featureType) {
		this.featureType = featureType;
	}

	public int getFeatureLevel() {
		return featureLevel;
	}

	public void setFeatureLevel(int featureLevel) {
		this.featureLevel = featureLevel;
	}	
	
	public int getGestSign() {
		return gestSign;
	}

	public void setGestSign(int gestSign) {
		this.gestSign = gestSign;
	}

	public int[] getFeatrueTmp() {
		return featrueTmp;
	}

	public void setFeatrueTmp(int[] featrueTmp) {
		this.featrueTmp = featrueTmp;
	}

	/**
	 * 在内部进行进行转换
	 * 
	 * @return
	 */
	public String getDower() {
		if (dowerMap != null) {
			if (dowerMap.isEmpty()) {
				return null;
			}
			String dowerString = null;
			try {
				dowerString = JsonProcesser.objectJsonEncode(dowerMap);
			} catch (Exception e) {
				e.printStackTrace();
			}

			return dowerString;
		} else {
			return dower;
		}
	}

	public void setDower(String dower) {
		if (dower != null) {
			try {
				dowerMap = JsonProcesser.objectJsonMapDecode(dower, Integer.class, Integer.class);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (dowerMap == null) {
			dowerMap = new HashMap<Integer, Integer>();
		}

		this.dower = dower;
	}

	public int getCreateTime() {
		return createTime;
	}

	public void setCreateTime(int createTime) {
		this.createTime = createTime;
	}

	public int getCampId() {
		return campId;
	}

	public void setCampId(int campId) {
		this.campId = campId;
	}

	public int getWorkId() {
		return workId;
	}

	public void setWorkId(int workId) {
		this.workId = workId;
	}

	public int getPosition() {
		return position;
	}

	public void setPosition(int position) {
		this.position = position;
	}

	public int getDevilTimes() {
		return devilTimes;
	}

	public void setDevilTimes(int devilTimes) {
		this.devilTimes = devilTimes;
	}

	public DiscipleMode getDiscipleMode() {
		return Context.getDiscipleServer().getDiscipleMode(discipleId);
	}

	public synchronized void alterExp(long alter) {
		exp += alter;
		autoUpLevel();// 检测是否升级
	}

	/**
	 * 徒弟检测是否升级
	 */
	private synchronized void autoUpLevel() {
		boolean isUp = false;
		while (exp >= getExpNeed()) {
			setExp(exp - getExpNeed());
			level = level + 1;
			isUp = true;
		}
		if (isUp) {
			clacPropertys();
		}
	}

	public void clacScore() {// 这里存在2处代码 DiscipleVO
		Player player = Context.getPlayerServer().getByPlayerId(playerId);
		score = FormulaScore.calcOneDisciple(this, player.getVocationId())[0];
	}

	public long getExpNeed() {
		LevelUpgrade levelUpgrade = LevelUpgrade.getByLevel(level);
		return levelUpgrade.getDiscipleExp();
	}

	public Map<Integer, Integer> getDowerMap() {
		return dowerMap;
	}

	public void setDowerMap(Map<Integer, Integer> dowerMap) {
		this.dowerMap = dowerMap;
	}

	public synchronized void clacPropertys() {
		int percentSum = powerPercent + physicalPercent + agilePercent + witPercent;

		power = growth * level * powerPercent / percentSum / 6;
		physical = growth * level * physicalPercent / percentSum / 6;
		agile = growth * level * agilePercent / percentSum / 6;
		wit = growth * level * witPercent / percentSum / 6;

		power = power <= 0 ? 1 : power;
		physical = physical <= 0 ? 1 : physical;
		agile = agile <= 0 ? 1 : agile;
		wit = wit <= 0 ? 1 : wit;

		if (devilTimes > 0 && devilTimes <= DiscipleConfig.devilMaxTimes) {
			int addValue = DiscipleConfig.devilAdd[devilTimes - 1];
			int qualifiedType =  getDiscipleMode().getQualifiedType();
			int[] xxx = new int[5];
			
			xxx[1] = addValue * powerPercent / percentSum;
			xxx[2] = addValue * physicalPercent / percentSum;
			xxx[3] = addValue * agilePercent / percentSum;
			xxx[4] = addValue * witPercent / percentSum;			
			xxx[qualifiedType] = 0 ;			
			xxx[qualifiedType] = addValue - xxx[1] - xxx[2] - xxx[3] - xxx[4];
			powerAdd = xxx[1];
			physicalAdd = xxx[2];
			agileAdd = xxx[3];
			witAdd = xxx[4];
		}

		power += powerAdd;
		physical += physicalAdd;
		agile += agileAdd;
		wit += witAdd;

		int ePower = 0, ePhysical = 0, eAgile = 0, eWit = 0;

		if (dowerMap.isEmpty() == false) {// 天赋增加自身属性
			for (Map.Entry<Integer, Integer> entry : dowerMap.entrySet()) {
				if (entry.getKey() < 15 || entry.getKey() > 18) {
					continue;
				}
				DiscipleDower discipleDower = DiscipleDower.getById(entry.getKey());
				if (discipleDower.getAdd() == null) {
					continue;
				}
				int addValue = discipleDower.getAdd()[entry.getValue() - 1];
				switch (entry.getKey()) {
				case 15:
					ePower += NumberProcesser.percentOnlyAddValue(power, addValue);
					break;
				case 16:
					ePhysical += NumberProcesser.percentOnlyAddValue(physical, addValue);
					break;
				case 17:
					eAgile += NumberProcesser.percentOnlyAddValue(agile, addValue);
					break;
				case 18:
					eWit += NumberProcesser.percentOnlyAddValue(wit, addValue);
					break;
				default:
					break;
				}
			}
		}

		power += ePower;
		physical += ePhysical;
		agile += eAgile;
		wit += eWit;

		clacScore();

	}
	
	@Deprecated
	public int clacTwoProperties(int source) {
		if (source == 0) {
			return 0;
		}
		int coefficient = 0;
		if (source <= 20) {
			coefficient = 10;
		} else if (source <= 30) {
			coefficient = 11;
		} else if (source <= 45) {
			coefficient = 12;
		} else if (source <= 65) {
			coefficient = 14;
		} else {
			coefficient = 18;
		}
		return source * coefficient / 10;
	}

	public DiscipleVO toVO() {
		return new DiscipleVO(this);
	}

	@Override
	public boolean syncDB() {
		return Context.getSyncServer().syncDB(this);
	}

	public DiscipleSmallVO toSmallVO() {
		return new DiscipleSmallVO(this);
	}

}
